package com.smart.thrift.discoveryandbalance.discovery.consul;

import com.orbitz.consul.AgentClient;
import com.orbitz.consul.Consul;
import com.orbitz.consul.OperatorClient;
import com.orbitz.consul.model.agent.ImmutableRegCheck;
import com.orbitz.consul.model.agent.ImmutableRegistration;
import com.orbitz.consul.model.agent.Registration;
import com.smart.thrift.constants.ThriftConstants;
import com.smart.thrift.discoveryandbalance.discovery.AbstractRegistry;
import com.smart.thrift.discoveryandbalance.discovery.ThriftServerNode;
import com.smart.thrift.exception.client.ThriftClientRegistryException;
import lombok.Getter;

import java.util.Objects;

public class ConsulRegistry extends AbstractRegistry<Consul> {

    private static final String HEALTH_CHECK_URL_TEMPLATE = "%s:%d";
    private static final Long CHECK_INTERVAL = 30L;
    private static final Long CHECK_TIMEOUT = 3L;

    private Consul consulClient;

    @Getter
    private final String clientType = ThriftConstants.DiscoveryType.CONSUL;
    private static ConsulRegistry consulRegistry;

    private ConsulRegistry(){}

    public static ConsulRegistry getInstance() {
        if (Objects.isNull(consulRegistry)) {
            consulRegistry = new ConsulRegistry();
            consulRegistry.createClient();
        }
        return consulRegistry;
    }

    @Override
    public Consul getClient() {
        return consulClient;
    }

    @Override
    public synchronized void register(String serviceName, String serverId, ThriftServerNode thriftServerNode){
        AgentClient agentClient = consulClient.agentClient();
        ImmutableRegistration.Builder builder = ImmutableRegistration.builder();
        builder.id(serverId)
                .name(serviceName)
                .address(thriftServerNode.getHost())
                .port(thriftServerNode.getPort())
                .tags(thriftServerNode.getTags())
                .enableTagOverride(false);
        String healthCheckUrl = String.format(HEALTH_CHECK_URL_TEMPLATE, thriftServerNode.getHost(), thriftServerNode.getPort());
        Registration.RegCheck regCheck = ImmutableRegCheck.tcp(healthCheckUrl, CHECK_INTERVAL, CHECK_TIMEOUT);
        builder.check(regCheck);
        agentClient.register(builder.build());
    }


    @Override
    public ThriftServerNode unregister(String serviceName, String serverId) {
        OperatorClient operatorClient = consulClient.operatorClient();
        return null;
    }

    public void createClient(){
        try {
            consulClient = Consul.builder().withUrl(getRegistryProperties().getConnectString()).build();
        } catch (Exception e) {
            throw new ThriftClientRegistryException("Unable to access consul server, address is: " + getRegistryProperties().getConnectString(), e);
        }
        if (Objects.isNull(consulClient)) {
            throw new ThriftClientRegistryException("Unable to access consul server, address is: " + getRegistryProperties().getConnectString());
        }
    }
}
